package cn.yx.common.jdbc.util;

import cn.hutool.core.util.ArrayUtil;
import cn.yx.common.core.enums.date.DatePatternEnum;
import cn.yx.common.core.exception.CommonException;
import cn.yx.common.core.util.date.DateParseUtil;
import cn.yx.common.jdbc.constant.message.JdbcUtilMessageKey;
import lombok.extern.slf4j.Slf4j;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * <p>JDBC工具类</p>
 *
 * @author Wggsmart
 */
@Slf4j
public final class JdbcUtil {

    private JdbcUtil() {
    }

    /**
     * 获取数据库连接
     *
     * @param driverClassName
     * @param url
     * @param username
     * @param password
     * @return
     */
    public static Connection connect(String driverClassName, String url, String username, String password) {
        try {
            Class.forName(driverClassName);
            return DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException | SQLException e) {
            log.error("connect to database error: {}", e.getMessage());
            throw new CommonException(JdbcUtilMessageKey.GET_CONNECTION_ERROR, e);
        }
    }

    /**
     * 关闭资源，如Connection, ResultSet等
     *
     * @param autoCloseable
     */
    public static void close(AutoCloseable autoCloseable) {
        try {
            autoCloseable.close();
        } catch (Exception e) {
            log.error("close error: {}", e.getMessage());
        }
    }

    /**
     * 获取字段对应的Java类型的名称
     *
     * @param jdbcType
     * @return
     */
    public static String getJavaType(String jdbcType) {
        if (ArrayUtil.contains(new String[]{"VARCHAR", "VARCHAR2", "CHAR", "TEXT", "LONGTEXT", "MEDIUMTEXT", "TINYTEXT"}, jdbcType)) {
            return "String";
        }
        if (ArrayUtil.contains(new String[]{"NUMBER", "DECIMAL"}, jdbcType)) {
            return "BigDecimal";
        }
        if (ArrayUtil.contains(new String[]{"INT", "INTEGER"}, jdbcType)) {
            return "Integer";
        }
        if (ArrayUtil.contains(new String[]{"SMALLINT"}, jdbcType)) {
            return "Short";
        }
        if (ArrayUtil.contains(new String[]{"TINYINT"}, jdbcType)) {
            return "Byte";
        }
        if (ArrayUtil.contains(new String[]{"BIGINT"}, jdbcType)) {
            return "Long";
        }
        if (ArrayUtil.contains(new String[]{"DOUBLE"}, jdbcType)) {
            return "Double";
        }
        if (ArrayUtil.contains(new String[]{"FLOAT"}, jdbcType)) {
            return "Float";
        }
        if (ArrayUtil.contains(new String[]{"DATETIME", "TIMESTAMP", "DATE", "TIME", "YEAR"}, jdbcType)) {
            return "Date";
        }
        return null;
    }

    /**
     * 根据jdbc type把字符中的值转化为与jdbc type对应的Java类型的值
     *
     * @param value
     * @param jdbcType
     * @return
     */
    public static Object convert(String value, String jdbcType) {
        if (ArrayUtil.contains(new String[]{"VARCHAR", "VARCHAR2", "CHAR", "TEXT", "LONGTEXT", "MEDIUMTEXT", "TINYTEXT"}, jdbcType)) {
            return value;
        }
        if (ArrayUtil.contains(new String[]{"NUMBER", "DECIMAL"}, jdbcType)) {
            return new BigDecimal(value);
        }
        if (ArrayUtil.contains(new String[]{"INT", "INTEGER"}, jdbcType)) {
            return Integer.valueOf(value);
        }
        if (ArrayUtil.contains(new String[]{"SMALLINT"}, jdbcType)) {
            return Short.valueOf(value);
        }
        if (ArrayUtil.contains(new String[]{"TINYINT"}, jdbcType)) {
            return Byte.valueOf(value);
        }
        if (ArrayUtil.contains(new String[]{"BIGINT"}, jdbcType)) {
            return Long.valueOf(value);
        }
        if (ArrayUtil.contains(new String[]{"DOUBLE"}, jdbcType)) {
            return Double.valueOf(value);
        }
        if (ArrayUtil.contains(new String[]{"FLOAT"}, jdbcType)) {
            return Float.valueOf(value);
        }
        if (ArrayUtil.contains(new String[]{"DATETIME", "TIMESTAMP", "DATE", "TIME", "YEAR"}, jdbcType)) {
            return DateParseUtil.parseDate(value, DatePatternEnum.DATETIME.getValue());
        }
        return null;
    }

}
